<?php

namespace app\admin\controller\customform;

use app\common\controller\Backend;
use app\common\exception\UploadException;
use app\common\library\Upload;
use think\Db;
use think\File;

/**
 *
 *
 * @icon fa fa-circle-o
 */
class Index extends Backend
{

    /**
     * Index模型对象
     * @var \app\admin\model\customform\Index
     */
    protected $model       = null;
    protected $noNeedRight = ['get_theme'];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\customform\Index;
        $this->view->assign("statusList", $this->model->getStatusList());
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = false;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total                                       = $this->model

                ->where($where)
                ->order($sort, $order)
                ->count();

            $list = $this->model

                ->where($where)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();

            foreach ($list as $row) {
                $row->visible(['id', 'title', 'is_login_switch', 'is_email_switch', 'status', 'weigh', 'createtime', 'updatetime']);

            }
            $list   = collection($list)->toArray();
            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }
        return $this->view->fetch();
    }

    //设计表单
    public function design()
    {
        $basefile = request()->baseFile();

        $this->assign("basefile", $basefile);
        $this->assign("token", $this->request->token());

        $this->view->engine->layout(false);

        return $this->view->fetch();
    }

    //获取单条配置数据
    public function design_data()
    {
        $id = input("id", 0, "intval");

        $result = db("customform")->where("id", $id)->find();

        if (!$result) {
            return json(['code' => 0, 'msg' => '数据不存在']);
        }

        $result['config'] = json_decode($result['config'], true);

        return json(['code' => 1, "data" => $result]);
    }

    //附件查询
    public function attachment()
    {
        $keyword  = $this->request->post('keyword', '');
        $page     = $this->request->post('page/d', 1);
        $limit    = $this->request->post('limit/d', 10);
        $mimetype = $this->request->post('mimetype', 'image');

        $where['mimetype'] = ['like', "%{$mimetype}%"];

        if ($keyword) {
            $where['filename'] = ['like', "%{$keyword}%"];
        }

        $list = db('attachment')->where($where)->field('id,url,filename')->order("id desc")->page($page, $limit)->select();

        foreach ($list as $key => $value) {
            $list[$key]['url'] = cdnurl($value['url'], true);
        }

        $total = db('attachment')->where($where)->count();

        return json(['code' => 1, 'data' => ['list' => $list, 'total' => $total]]);
    }

    //保存数据
    public function design_save()
    {
        $id = input("id", 0, "intval");

        $result = db("customform")->where("id", $id)->find();

        if (!$result) {
            return json(['code' => 0, 'msg' => '数据不存在']);
        }

        $data = input("data");
        $data = htmlspecialchars_decode($data);
        $data = html_entity_decode($data);

        $rs = db("customform")->where("id", $id)->update(['updatetime' => time(), 'config' => $data]);

        if ($rs) {
            return json(['code' => 1, 'msg' => '保存成功']);
        } else {
            return json(['code' => 0, 'msg' => '保存失败']);
        }
    }

    //用户表单数据查询
    public function edit_data()
    {
        $id = input("id", 0, "intval");

        $result = db("customform_data")->alias("a")->join("customform b", "a.customform_id = b.id")->field("a.*,b.config")->where("a.id", $id)->find();

        if (!$result) {
            return json(['code' => 0, 'msg' => '数据不存在']);
        }

        $result['config'] = json_decode($result['config'], true);

        $result['data'] = json_decode($result['data'], true);

        $result['config']['dataconfig'] = $this->search_add_value($result['config']['dataconfig'], $result['data']);

        return json(['code' => 1, "data" => $result]);
    }

    //更新用户表单数据
    public function save_data()
    {
        $id    = input("id", 0, "intval");
        $data  = input("data/a", [], 'htmlspecialchars');
        $token = input("__token__", '');

        $validate = $this->validate(
            [
                'id'        => $id,
                '__token__' => $token,
            ],
            [
                'id'        => 'require',
                '__token__' => 'require|token',
            ]);
        if (true !== $validate) {
            // 验证失败 输出错误信息
            return json(['code' => 0, 'msg' => $validate, '__token__' => $this->request->token()]);
        }

        $result = db("customform_data")->alias("a")->join("customform b", "a.customform_id = b.id")->field("a.*,b.config")->where("a.id", $id)->find();

        if (!$result) {

            return json(['code' => 0, 'msg' => '数据不存在', '__token__' => $this->request->token()]);
        }

        $result['config'] = json_decode($result['config'], true);

        $newdata = [];

        foreach ($data as $key => $value) {
            $newdata[] = ["id" => $key, "value" => $value];
        }

        if (count($newdata) == 0) {
            return json(['code' => 0, 'msg' => '数据不能为空', '__token__' => $this->request->token()]);
        }

        //需后台记录的字段
        $showfield = $result['config']['formconfig']['showfield'];
        //显示字段
        $showfieldlist = $result['config']['formconfig']['showfieldlist'];

        //查询需后台记录的字段是否存在，不存在则默认前一行作为标题
        if (count($showfield) > 0) {

            foreach ($showfield as $key => $value) {
                foreach ($newdata as $keys => $values) {
                    if ($value == $values['id']) {
                        //递归出标题
                        $name         = $this->search_title($value, $result['config']['dataconfig']);
                        $title[$name] = $values['value'];
                        continue;
                    }
                }
            }

            if (empty($title)) {
                foreach ($showfieldlist as $key => $value) {
                    if ($value['id'] == $showfield[0]) {
                        return json(['code' => 0, 'msg' => $value['name'] . '字段不能为空', 'data' => $showfield[0], '__token__' => $this->request->token()]);
                    }
                }
            }

        } else {
            $name         = $this->search_title($newdata[0]['id'], $result['config']['dataconfig']);
            $title[$name] = $newdata[0]['value'];
        }

        //查询必须填写的值
        $nempty_list = $this->nempty_value($result['config']['dataconfig']);
        //联动事件规则
        $linkageEvent = $result['config']['linkageEvent'];
        //过滤不检验的数组
        $linkageEventArray = [];
        
        //过滤出符合规则并且隐藏的字段
        foreach ($linkageEvent as $key => $value) {
            $event_status = true;
            foreach ($value['from'] as $keys => $values) {
                if( !isset($data[$values['id']]) || $data[$values['id']] != $values['value']){
                    $event_status = false;
                }
            }
            if($event_status){
                //过滤数组增加元素
                foreach ($value['obj'] as $keys => $values) {
                    $linkageEventArray[] = $values['id'];
                }
            }
        }
        //递归过滤数据，判断是否为容器，若为容器则增加容器里的字段
        foreach ($linkageEventArray as $key => $value) {
            if(!isset($data[$value])){
                $box_id = $value;
                unset($linkageEventArray[$key]);
                $linkageEventArray = array_merge($linkageEventArray,$this->get_box_list($result['config']['dataconfig'],$box_id));
            }
        }

        foreach ($nempty_list as $key => $value) {
            //检验数据是否存在
            if (!$this->search_value($newdata, $value)) {
                if(array_search((string)$value['id'],$linkageEventArray) === false){
                    return json(['code' => 0, 'msg' => $value['config']['label'] . $value['config']['message'], 'data' => $value['id'], '__token__' => $this->request->token()]);
                }
            }
        }

        //如果存在过滤字段已输入内容，则清除
        foreach ($newdata as $key => $value) {
            if(array_search((string)$value['id'],$linkageEventArray) !== false){
                unset($newdata[$key]);
            }
        }

        $rs = db("customform_data")->where('id', $id)->update(['title' => json_encode($title, JSON_UNESCAPED_UNICODE), 'data' => json_encode($newdata), 'updatetime' => time()]);

        if ($rs) {
            return json(['code' => 1, 'msg' => '修改成功', '__token__' => $this->request->token()]);
        } else {
            return json(['code' => 0, 'msg' => '修改失败，请重试', '__token__' => $this->request->token()]);
        }

    }

    //根据id搜索字段
    protected function get_box_list($array,$id)
    {
        foreach ($array as $key => $value) {
            if($value['id'] == $id && !empty($value['list'])){
                return $this->get_box_all($value['list']);
            }
        }
        return false;
    }

    //递归返回过滤字段
    protected function get_box_all($array)
    {
        $new_array = [];
        foreach ($array as $key => $value) {
            if (empty($value['list'])) {
                $new_array[] = $value['id'];
            } else {
                $new_array = array_merge($new_array, $this->get_box_all($value['list']));
            }
        }
        return $new_array;
    }

    
    //查询lable
    protected function search_title($id, $array)
    {
        foreach ($array as $key => $value) {
            if (empty($value['list'])) {
                if ($value['id'] == $id) {
                    return $value['config']['label'];
                }
            } else {
                return $this->search_title($id, $value['list']);
            }
        }
    }

    //递归赋值数据
    protected function search_add_value($array, $data)
    {
        foreach ($array as $key => $value) {
            if (empty($value['list'])) {
                foreach ($data as $keys => $values) {
                    if ($value['id'] == $values['id']) {
                        $array[$key]['config']['value'] = $values['value'];
                        unset($data[$keys]);
                    }
                }
            } else {
                $array[$key]['list'] = $this->search_add_value($value['list'], $data);
            }
        }

        return $array;
    }

    //检验提交值
    protected function search_value($array, $data)
    {
        $check = false;

        foreach ($array as $key => $value) {
            if ($value['id'] == $data['id']) {
                //正则不为空
                if (($data['config']['regular'] && !preg_match($data['config']['regular'], $value['value'])) || empty($value['value'])) {

                    return false;
                } else {
                    $check = true;
                    continue;
                }
            }
        }

        return $check;
    }

    //查询总数据中不能为空的值
    protected function nempty_value($array)
    {
        $new_array = [];
        foreach ($array as $key => $value) {
            if (empty($value['list'])) {
                if (!empty($value['config']['required'])) {
                    $new_array[] = $value;
                }
            } else {
                $new_array = array_merge($new_array, $this->nempty_value($value['list']));
            }
        }

        return $new_array;
    }

    public function get_theme()
    {
        $page  = $this->request->post('page/d', 1);
        $limit = $this->request->post('limit/d', 10);

        $list  = db("customform")->page($page, $limit)->order('id desc')->select();
        $count = db("customform")->count();

        return json(['code' => 1, 'data' => ['list' => $list, 'count' => $count]]);
    }

    //保存base64图片
    public function save_sign_img()
    {
        $imgdata = $this->request->post('imgdata', '');

        if (!$imgdata) {
            return json(['code' => 0, 'msg' => '图片数据错误']);
        }

        $reg = '/data:image\/(\w+?);base64,(.+)$/si';
        preg_match($reg, $imgdata, $match_result);

        if (!in_array($match_result[1], ['png', 'jpg'])) {
            return json(['code' => 0, 'msg' => '图片数据错误']);
        }

        $file_name = uniqid() . '.' . $match_result[1];

        $wwwpath = DS . 'uploads' . DS . date('Ymd');
        $path    = ROOT_PATH . 'runtime' . DS . 'addons' . DS . 'customform' . $wwwpath;

        if (!is_dir($path)) {
            @mkdir($path, 0755, true);
        }

        file_put_contents($path . DS . $file_name, base64_decode($match_result[2]));

        try {
            $file_info = getimagesize($path . DS . $file_name);

            if (!$file_info || !isset($file_info[0]) || !isset($file_info[1])) {
                throw new UploadException('当前文件不是图片');
            }

            $file_more = [
                "type"     => $file_info['mime'],
                "suffix"   => $match_result[1],
                "name"     => $file_name,
                "size"     => filesize($path . DS . $file_name),
                "tmp_name" => $path . DS . $file_name,
            ];

            $file = (new File($path . DS . $file_name))->setUploadInfo($file_more);
            $file->isTest(true);
            $upload     = new Upload($file);
            $attachment = $upload->upload();
        } catch (UploadException $e) {
            unlink($path . DS . $file_name);
            return json(['code' => 0, 'msg' => $e->getMessage()]);
        }

        return json(['code' => 1, 'data' => $attachment->url]);
    }
}
